﻿
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using GBFramework;
using LuaInterface;
using UObject = UnityEngine.Object;

public class UpdateFileInfo
{
    public string filePath;
    public string md5;
    public float fileSize;

    public UpdateFileInfo(string content)
    {
        string[] one = content.Split(new string[] { "|" }, System.StringSplitOptions.RemoveEmptyEntries);
        filePath = one[0];
        md5 = one[1];
        fileSize = float.Parse(one[2]);
    }

    public bool equal(UpdateFileInfo other)
    {
        return md5.Equals(other.md5);
    }
}

public class FileData
{
    public string fileName;
    public string filePath;
    public string fileChangeTime;
    public string fileStatus;
    public string fileType;

    public static string fileNameAttribute = "fileName";
    public static string filePathAttribute = "filePath";
    public static string fileChangeTimeAttribute = "fileChangeTime";
    public static string fileStatusAttribute = "fileStatus";
    public static string fileTypeAttribute = "fileType";
}

public enum FileType
{
    file,
    floder,
}

public enum FileStatus
{
    add,
    delete,
    chang,
    over,
}

namespace GBFramework {

    public delegate void LoadSceneCallBack(AsyncOperation async);
    public delegate void LoadAllAssetCallBack(UnityEngine.Object[] obj);
    public delegate void LoadAssetCallBack(UnityEngine.Object obj);
    public delegate void LoadSpriteCallBack(UnityEngine.Sprite sprite);
    public delegate void LoadTextureCallBack(UnityEngine.Texture texture);
    public delegate void LoadGameObjectCallBack(UnityEngine.GameObject obj, string abName, params object[] args);

    public class ResourceManager : Manager {
        private string[] m_Variants = { };
        private AssetBundleManifest manifest;
        private AssetBundle shared, assetbundle;
        private Dictionary<string, AssetBundle> bundles;

        void Awake() {

            AssetBundleLoader abLoadComponent = Util.Add<AssetBundleLoader>(gameObject);
            DontDestroyOnLoad(abLoadComponent);
        }

        Sprite spriteObj = null;
        public void LoadAllSpriteAsync(string path, LoadAllSpriteCallBack fn)
        {
            string bundleName = path.ToLower();
            string assetName = path + ".png";
            AssetBundleLoader.Instance.LoadAllAssetAsync(bundleName, assetName,
                (arr) =>
                {
                    if (fn != null) { fn(arr, bundleName); }
                });
        }

        GameObject prefabObj;
        public void loadGameObjectAsyncToCache(string path, LoadGameObjectCallBack fn, bool bDestroy, params object[] args)
        {
            string bundleName = path.ToLower();
            string assetName = path + ".prefab";
            AssetBundleLoader.Instance.LoadAssetAsync(bundleName, assetName,
                (obj) =>
                {
                    if(obj != null)
                    {
                        prefabObj = obj as GameObject;
                        if (fn != null) fn(prefabObj, bundleName, args);
                    }
                    else
                    {
                        if (fn != null) fn(null, bundleName, args);
                    }
                }, bDestroy);
        }

        Dictionary<string, int> dicLoadBundleSet = new Dictionary<string, int>();

        public void saveBundleToList(string bundleName)
        {
            int refCount;
            if (dicLoadBundleSet.TryGetValue(bundleName, out refCount))
                dicLoadBundleSet[bundleName] = refCount + 1;
            else
                dicLoadBundleSet.Add(bundleName, 1);
        }

        public void unloadAssetName(string path)
        {
            int countRef = 0;
            string pathName = path.ToLower();

            if(dicLoadBundleSet.TryGetValue(pathName, out countRef))
            {
                AssetBundleManager.UnloadAssetBundle(pathName, true);
                dicLoadBundleSet[pathName] = countRef - 1;
            }

            if(countRef <=1)
            {
                dicLoadBundleSet.Remove(pathName);
            }
        }

        public void unloadAllBundle()
        {
            string keyValue = "";
            int nLenght = 0;
            Dictionary<string, int>.Enumerator em = dicLoadBundleSet.GetEnumerator();
            while(em.MoveNext())
            {
                keyValue = em.Current.Key;
                nLenght = em.Current.Value;
                for (int i = 0; i < nLenght; i++)
                {
                    AssetBundleManager.UnloadAssetBundle(keyValue, true);
                }
            }
            dicLoadBundleSet.Clear();
        }


        public static void CreateFolder(string path)
        {
            if(!Directory.Exists(path))
            {
                string lastPath = GetFileOrFloderLastPath(path);
                List<string> floderPath = new List<string>();
                floderPath.Add(path);
                while(true)
                {
                    if(Directory.Exists(lastPath))
                    {
                        break;
                    }
                    else
                    {
                        floderPath.Add(lastPath);
                        lastPath = GetFileOrFloderLastPath(lastPath);
                    }
                }
                for (int i = 0; i < floderPath.Count; i++)
                {
                    Directory.CreateDirectory(floderPath[i]);
                }
            }
        }

        public static string GetFileOrFloderLastPath(string path)
        {
            string[] paths = path.Split('/');
            string floderPath = "";
            if(paths.Length > 0)
            {
                floderPath = paths[0];
                for(int i=1; i<paths.Length-1; i++)
                {
                    floderPath += "/" + paths[i];
                }
                return floderPath;
            }
            return null;
        }

        public string getFilePath(string path)
        {
#if UNITY_EDITOR
            return Globals.streamingPath + "/" + path;
#else
            return Globals.persistenPath + "/" + path;
#endif
        }
    }
}
